#pragma once
#include "nnse_support.h"

namespace nnse
{
	template <class T, class U> public ref class dendrite
	{
		// Constructor and Destructor
			public: dendrite(neuron<T, U>^ p, unsigned int d_n);
			public: virtual ~dendrite();
		// Member Variables and their Accessor Functions
			// parent - the neuron to which this dendrite belongs
				private: neuron<T, U>^ parent;
				public: MLP<T, U>^ get_parent_MLP();
				public: neuron<T, U>^ get_parent_neuron();
			// number - the dendrite's number relative to the other dendrites in the parent neuron
				private: unsigned int number;
				public: unsigned int get_number();
				protected: void put_number(unsigned int n);
			// weight - the dendrite's connection strength
				private: U weight;
				public: U get_weight();
				protected: void put_weight(U w);
			// input - the input signal to the dendrite
				private: U input;
				public: U get_input();
				public: void put_input(U i);
			// output - the output signal from the dendrite
				private: U output;
				public: U get_output();
				protected: void put_output();
			// previous_weight_change - the last change to the dendrite's connection strength (used by momentum)
				private: U previous_weight_change;
				public: U get_previous_weight_change();
				protected: void put_previous_weight_change(U p_w_c);
			// dendrite_form - the dendrite's user interface
				protected: SimpleGUI::Dendrite<T, U>^ dendrite_form;
		// Worker Functions
			public: void update_weight(U OUT, U DELTA);
			protected: virtual U calc_output();
			protected: virtual U calc_weight_change(U OUT, U DELTA);
		// GUI Functions
			public: void display_form();
			public: void invalidate_form();
		// Serialisation Functions
			public: virtual void read(std::wifstream& in);
			public: virtual void write(std::wofstream& out);
			public: virtual void display(std::wofstream& out);
	};
	template <class T, class U> std::wifstream& operator>>(std::wifstream& in, dendrite<T, U>% d);
	template <class T, class U> std::wofstream& operator<<(std::wofstream& out, dendrite<T, U>% d);
}
